package com.xique.park.service.biz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xique.common.core.utils.*;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.common.datascope.annotation.NeedSetDictLabel;
import com.xique.common.datascope.annotation.NeedSetFieldValue;
import com.xique.common.redis.service.RedisService;
import com.xique.park.bean.domain.*;
import com.xique.park.bean.domain.client.ClientLaneConfig;
import com.xique.park.bean.domain.client.ParkClient;
import com.xique.park.bean.domain.client.ParkClientUser;
import com.xique.park.bean.request.client.ClientCancelPassRequest;
import com.xique.park.bean.request.client.ClientCashPassListRequest;
import com.xique.park.bean.request.client.ClientHandOutInfoRequest;
import com.xique.park.bean.request.client.ClientSpaceEditRequest;
import com.xique.park.bean.transform.client.ClientHomePageTransfer;
import com.xique.park.bean.vo.client.*;
import com.xique.park.constant.RedisConstants;
import com.xique.park.controller.client.web.bean.dto.ParkInOut;
import com.xique.park.controller.client.web.bean.request.ClientParkOnListRequest;
import com.xique.park.controller.client.web.service.biz.service.IClientCommandService;
import com.xique.park.mapper.*;
import com.xique.park.mapper.client.ParkClientMapper;
import com.xique.park.mapper.client.ParkClientUserMapper;
import com.xique.park.service.biz.service.IClientBizService;
import com.xique.park.service.service.*;
import com.xique.park.utils.RedisUtil;
import com.xique.system.api.RemoteSystemDictService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * @author: caogq
 * @Date: 2021/7/26 09:38
 * @Description:
 */
@Slf4j
@Service
public class ClientBizServiceImpl implements IClientBizService {

    @Autowired
    private IParkLaneService parkLaneService;

    @Autowired
    private ParkClientMapper parkClientMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private ParkOutMapper parkOutMapper;

    @Autowired
    private ParkOnMapper parkOnMapper;

    @Autowired
    private ParkDeviceNewMapper parkDeviceNewMapper;

    @Autowired
    private IParkInService parkInService;

    @Autowired
    private IParkOutService parkOutService;

    @Autowired
    private ParkClientUserMapper parkClientUserMapper;

    @Autowired
    private ParkInfoMapper parkInfoMapper;

    @Autowired
    private ClientHomePageTransfer clientHomePageTransfer;

    @Autowired
    private AliossUtil aliossUtil;

    @Autowired
    private IParkCarMngtypeService parkCarMngtypeService;

    @Autowired
    private ParkingOrderMapper parkingOrderMapper;

    @Autowired
    private IParkGarageService parkGarageService;

    @Autowired
    private IClientCommandService clientCommandService;

    @Autowired
    private IParkDeviceNewService parkDeviceNewService;

    @Autowired
    private IClientLaneConfigService clientLaneConfigService;

    @Autowired
    private RemoteSystemDictService remoteSystemDictService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public AjaxResult getHomePageInfo(String clientId) {
        try {
            ParkClient parkClient = parkClientMapper.selectParkClientById(Long.valueOf(clientId));
            if (parkClient == null) {
                return null;
            }
            ClientHomePageVo clientHomePageVo = new ClientHomePageVo();

            // 查询当前岗亭的通道信息 通道（设备）
            long parkId = parkClient.getParkId();
            List<ClientLaneVo> clientLaneVos = parkLaneService.selectParkLaneByClient(parkId, clientId);
            List<ClientDeviceVo> deviceVos = new ArrayList<>();
            List<Long> inLanes = new ArrayList<>();
            List<Long> outLanes = new ArrayList<>();
            for (ClientLaneVo laneVo : clientLaneVos) {
                List<ClientDeviceVo> majorDevices = laneVo.getClientDeviceVos().stream().filter(deviceVo -> "Y".equals(deviceVo.getIsMain())).collect(Collectors.toList());
                if (!majorDevices.isEmpty()) {
                    laneVo.setMainSn(majorDevices.get(0).getCode());
                }
                String str = redisService.getCacheObject("jzy:lane:sense:" + Long.parseLong(laneVo.getId()));
                JSONObject object = JSON.parseObject(str);
                if (null != object) {
                    laneVo.setSenseStatus(object.getString("is_sense"));
                    laneVo.setGateStatus(object.getString("is_gate_state"));
                }
                deviceVos.addAll(laneVo.getClientDeviceVos());

                if ("1".equals(laneVo.getLaneType())) {
                    inLanes.add(Long.parseLong(laneVo.getId()));
                }
                if ("2".equals(laneVo.getLaneType()) || "3".equals(laneVo.getLaneType()) || "4".equals(laneVo.getLaneType())) {
                    outLanes.add(Long.parseLong(laneVo.getId()));
                }
            }

            // 1.查询岗亭的值班信息
            Future<ClientUserVO> clientUserVoFuture = threadPoolTaskExecutor.submit(() -> selectClientInfo(parkId, parkClient, clientId));

            // 2.查询对应通道下最新进出记录
            Future<List<ClientLaneVo>> lastParkInOrOutListFuture = threadPoolTaskExecutor.submit(() -> selectLastParkInOrOutListByLaneId(parkId, inLanes, outLanes, clientLaneVos));

            // 3.查询设备状态
            Future<List<ClientDeviceVo>> deviceOnLineStatusFuture = threadPoolTaskExecutor.submit(() -> deviceOnLineStatus(parkId, deviceVos));

            // 4.查询最新的五条入场记录
            Future<List<ClientParkInVo>> parkInVosFuture = threadPoolTaskExecutor.submit(() -> selectTop5ClientParkIn(parkId, parkClient));

            // 5.查询最新的五条出场记录
            Future<List<ClientParkOutVo>> parkOutVosFuture = threadPoolTaskExecutor.submit(() -> selectTop5ClientParkOut(parkId, parkClient));

            // 6.查询岗亭基本信息
            Future<ClientVo> clientVoFuture = threadPoolTaskExecutor.submit(() -> selectParkInfoById(parkId, parkClient));

            clientHomePageVo.setLaneList(clientLaneVos);
            lastParkInOrOutListFuture.get();
            deviceOnLineStatusFuture.get();
            clientHomePageVo.setUserVO(clientUserVoFuture.get());
            clientHomePageVo.setParkInVos(parkInVosFuture.get());
            clientHomePageVo.setParkOutVos(parkOutVosFuture.get());
            clientHomePageVo.setClientVo(clientVoFuture.get());

            return AjaxResult.success(clientHomePageVo);
        } catch (Exception e) {
            e.printStackTrace();
            if (e instanceof InterruptedException) {
                Thread.currentThread().interrupt();
            }
            return AjaxResult.error("系统异常");
        }
    }

    private ClientVo selectParkInfoById(Long parkId, ParkClient parkClient) {
        long startTime = System.currentTimeMillis();
        ParkInfo parkInfo = parkInfoMapper.selectParkInfoById(parkClient.getParkId());
        ClientVo clientVo = OrikaUtil.convert(parkClient, ClientVo.class);
        clientVo.setParkName(parkInfo.getName());
        log.info("[PC岗亭]-首页，查询岗亭基本信息，车场ID：{}，岗亭ID；{}，查询耗时：{}", parkId, parkInfo.getId(), System.currentTimeMillis() - startTime);
        return clientVo;
    }

    private List<ClientParkOutVo> selectTop5ClientParkOut(Long parkId, ParkClient parkClient) {
        long startTime = System.currentTimeMillis();
        List<ClientParkOutVo> parkOutVos = new ArrayList<>();
        // 根据岗亭ID获取岗亭关联的通道信息
        List<ClientLaneConfig> clientLaneConfigList = clientLaneConfigService.selectListByClientId(parkClient.getId());
        if (CollUtil.isNotEmpty(clientLaneConfigList)) {
            List<Long> laneIdList = clientLaneConfigList.stream().map(ClientLaneConfig::getLaneId).collect(Collectors.toList());
            // 获取最新的五条出场记录的ID
            int limit = 5;
            List<ParkOut> parkOutList = parkOutService.selectParkOutIdByOutLaneId(parkId, laneIdList, limit);
            if (CollUtil.isNotEmpty(parkOutList)) {
                List<Long> parkOutIdList = parkOutList.stream().map(ParkOut::getId).collect(Collectors.toList());
                List<ParkOut> parkOuts = parkOutService.selectParkOutByIds(parkOutIdList);
                parkOuts.forEach(parkOut -> parkOutVos.add(clientHomePageTransfer.parkOutTransferClientParkOutVo(parkOut)));
            }
        }
        log.info("[PC岗亭]-首页，查询最新的五条出场记录，车场ID：{}，查询耗时：{}", parkId, System.currentTimeMillis() - startTime);
        return parkOutVos;
    }

    private List<ClientParkInVo> selectTop5ClientParkIn(Long parkId, ParkClient parkClient) {
        long startTime = System.currentTimeMillis();
        List<ClientParkInVo> parkInVos = new ArrayList<>();
        // 根据岗亭ID获取岗亭关联的通道信息
        List<ClientLaneConfig> clientLaneConfigList = clientLaneConfigService.selectListByClientId(parkClient.getId());
        if (CollUtil.isNotEmpty(clientLaneConfigList)) {
            List<Long> laneIdList = clientLaneConfigList.stream().map(ClientLaneConfig::getLaneId).collect(Collectors.toList());
            // 获取最新的五条入场记录的ID
            int limit = 5;
            List<ParkIn> parkInList = parkInService.selectParkInIdByInLaneId(parkId, laneIdList, limit);
            if (CollUtil.isNotEmpty(parkInList)) {
                List<Long> parkInIdList = parkInList.stream().map(ParkIn::getId).collect(Collectors.toList());
                List<ParkIn> parkIns = parkInService.selectParkInByIds(parkInIdList);
                parkIns.forEach(parkIn -> parkInVos.add(clientHomePageTransfer.parkInTransferClientParkInVo(parkIn)));
            }
        }
        log.info("[PC岗亭]-首页，查询最新的五条入场记录，车场ID：{}，查询耗时：{}", parkId, System.currentTimeMillis() - startTime);
        return parkInVos;
    }

    private ClientUserVO selectClientInfo(Long parkId, ParkClient parkClient, String clientId) {
        long startTime = System.currentTimeMillis();
        ClientUserVO clientUserVO = new ClientUserVO();
        ParkClientUser parkClientUser = parkClientUserMapper.selectParkClientUserById(parkClient.getSysUserId());
        if (null != parkClientUser) {
            clientUserVO.setName(parkClientUser.getUserName());
        }
        if (parkClient.getLoginTime() != null) {
            clientUserVO.setLoginTime(DateUtils.parseDateToStr("MM/dd HH:mm", parkClient.getLoginTime()));
            double sumCash = parkClientMapper.sumClientCash(parkClient.getLoginTime(), String.valueOf(parkClient.getSysUserId()), clientId);
            double sumFreeFee = parkClientMapper.sumClientFreeFee(parkClient.getLoginTime(), String.valueOf(parkClient.getSysUserId()), String.valueOf(parkClient.getId()));
            double sumWaitFee = parkClientMapper.sumClientWaitFee(parkClient.getLoginTime(), parkClient.getId(), parkClient.getParkId());

            //计算当前值班人员今日现金收费情况
            clientUserVO.setCashRelease(sumCash);
            clientUserVO.setFreeRelease(sumFreeFee);
            clientUserVO.setWaitRelease(sumWaitFee);

            //计算值班人员手动开闸次数  add by xl.liu 2022/02/17
            Integer openGateCnt = parkClientMapper.sumOpenGateCnt(parkClient.getLoginTime(), String.valueOf(parkClient.getSysUserId()), parkClient.getParkId());
            clientUserVO.setOpenGateCnt(openGateCnt);
        }
        log.info("[PC岗亭]-首页，查询岗亭值班信息，车场ID：{}，查询耗时：{}", parkId, System.currentTimeMillis() - startTime);
        return clientUserVO;
    }

    private List<ClientDeviceVo> deviceOnLineStatus(Long parkId, List<ClientDeviceVo> deviceVos) {
        long startTime = System.currentTimeMillis();
        List<Long> deviceIds = deviceVos.stream().map(ClientDeviceVo::getId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(deviceIds)) {
            List<ParkDeviceNew> parkDeviceNewList = parkDeviceNewService.listByIds(deviceIds);
            if (CollectionUtils.isNotEmpty(parkDeviceNewList)) {
                Map<Long, String> onLineStatusMap = parkDeviceNewList.stream().filter(v -> StringUtils.isNotEmpty(v.getOnlineStatus())).collect(Collectors.toMap(ParkDeviceNew::getId, ParkDeviceNew::getOnlineStatus));
                deviceVos.forEach(item -> {
                    if (StringUtils.isNotEmpty(onLineStatusMap.get(item.getId()))) {
                        JSONObject onlineStatus = JSON.parseObject(onLineStatusMap.get(item.getId()));
                        item.setState(onlineStatus.getString("state"));
                    }
                });
            }
        }
        log.info("[PC岗亭]-首页，查询设备状态，车场ID：{}，查询耗时：{}", parkId, System.currentTimeMillis() - startTime);
        return deviceVos;
    }

    private List<ClientLaneVo> selectLastParkInOrOutListByLaneId(Long parkId, List<Long> inLanes, List<Long> outLanes, List<ClientLaneVo> clientLaneVos) {
        long startTime = System.currentTimeMillis();
        selectLastParkInListByLaneId(parkId, inLanes, clientLaneVos);
        selectLastParkOutListByLaneId(parkId, outLanes, clientLaneVos);
        log.info("[PC岗亭]-首页，查询对应通道下最新进出记录，车场ID：{}，查询耗时：{}", parkId, System.currentTimeMillis() - startTime);
        return clientLaneVos;
    }

    private void selectLastParkInListByLaneId(Long parkId, List<Long> inLanes, List<ClientLaneVo> clientLaneVos) {
        Map<Long, ClientParkInVo> parkInVoMap = new HashMap<>(inLanes.size());

        inLanes.forEach(laneId -> {
            // 对应通道下放入最新记录
            String parkingOrderOnStr = (String) redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_PARKINGORDER_PREFIX + laneId);
            if (StrUtil.isNotBlank(parkingOrderOnStr)) {
                JSONObject jsonObject = (JSONObject) JSON.parse(parkingOrderOnStr);
                ParkingOrderOn parkingOrderOn = JSON.parseObject(jsonObject.get("ParkingOrder").toString(), ParkingOrderOn.class);
                if (parkingOrderOn != null) {
                    String parkingSerial = parkingOrderOn.getParkingSerial();
                    if (StrUtil.isNotEmpty(parkingSerial)) {
                        // 根据停车流水号获取进场记录
                        ParkIn search = new ParkIn();
                        search.setParkId(parkId);
                        search.setParkingSerial(parkingSerial);
                        List<ParkIn> parkInList = parkInService.selectParkIn(search);
                        if (CollUtil.isNotEmpty(parkInList)) {
                            ParkIn parkIn = parkInList.get(0);
                            ClientParkInVo clientParkInVo = clientHomePageTransfer.parkInTransferClientParkInVo(parkIn);
                            parkInVoMap.put(laneId, clientParkInVo);
                        }
                    }
                }
            }
        });

        clientLaneVos.forEach(clientLaneVo -> {
            ClientParkInVo clientParkInVo = parkInVoMap.get(Long.parseLong(clientLaneVo.getId()));
            if (null != clientParkInVo) {
                List<Object> recordList = new ArrayList<>(1);
                recordList.add(clientParkInVo);
                clientLaneVo.setRecord(recordList);
            }
        });

//        // 对应通道下放入最新记录
//        List<ParkIn> parkInList = parkInService.selectLastParkInListByLaneId(parkId, inLanes);
//        Map<Long, ClientParkInVo> parkInMap = parkInList.stream().collect(Collectors.groupingBy(ParkIn::getInLaneId, Collectors.collectingAndThen(Collectors.toList(), v -> clientHomePageTransfer.parkInTransferClientParkInVo(v.get(0)))));
//        for (ClientLaneVo laneVo : clientLaneVos) {
//            ClientParkInVo vo = parkInMap.get(Long.parseLong(laneVo.getId()));
//            if (null != vo) {
//                List<Object> recordList = new ArrayList<>(1);
//                recordList.add(vo);
//                laneVo.setRecord(recordList);
//            }
//        }
    }

    private void selectLastParkOutListByLaneId(Long parkId, List<Long> outLanes, List<ClientLaneVo> clientLaneVos) {
        Map<Long, ClientParkOutVo> parkOutVoMap = new HashMap<>(outLanes.size());

        outLanes.forEach(laneId -> {
            // 对应通道下出场最新记录
            String parkingOrderOnStr = (String) redisUtil.get(RedisConstants.REDIS_COMM_PREFIX + RedisConstants.REDIS_LANE_PARKINGORDER_PREFIX + laneId);
            if (StrUtil.isNotBlank(parkingOrderOnStr)) {
                JSONObject jsonObject = (JSONObject) JSON.parse(parkingOrderOnStr);
                ParkingOrderOn parkingOrderOn = JSON.parseObject(jsonObject.get("ParkingOrder").toString(), ParkingOrderOn.class);
                if (parkingOrderOn != null) {
                    String parkingSerial = parkingOrderOn.getParkingSerial();
                    if (StrUtil.isNotEmpty(parkingSerial)) {
                        // 根据停车流水号获取进场记录
                        ParkOut search = new ParkOut();
                        search.setParkId(parkId);
                        search.setParkingSerial(parkingSerial);
                        List<ParkOut> parkOutList = parkOutService.selectParkOut(search);
                        if (CollUtil.isNotEmpty(parkOutList)) {
                            ParkOut parkOut = parkOutList.get(0);
                            ClientParkOutVo clientParkOutVo = clientHomePageTransfer.parkOutTransferClientParkOutVo(parkOut);
                            parkOutVoMap.put(laneId, clientParkOutVo);
                        }
                    }
                }
            }
        });

        clientLaneVos.forEach(clientLaneVo -> {
            ClientParkOutVo clientParkOutVo = parkOutVoMap.get(Long.parseLong(clientLaneVo.getId()));
            if (null != clientParkOutVo) {
                List<Object> recordList = new ArrayList<>(1);
                recordList.add(clientParkOutVo);
                clientLaneVo.setRecord(recordList);
            }
        });

//        List<ParkOut> parkOutList = parkOutService.selectLastParkOutListByLaneId(parkId, outLanes);
//        Map<Long, ClientParkOutVo> parkOutMap = parkOutList.stream().collect(Collectors.groupingBy(ParkOut::getOutLaneId, Collectors.collectingAndThen(Collectors.toList(), v -> clientHomePageTransfer.parkOutTransferClientParkOutVo(v.get(0)))));
//        for (ClientLaneVo laneVo : clientLaneVos) {
//            ClientParkOutVo vo = parkOutMap.get(Long.parseLong(laneVo.getId()));
//            if (null != vo) {
//                List<Object> recordList = new ArrayList<>(1);
//                recordList.add(vo);
//                laneVo.setRecord(recordList);
//            }
//        }
    }

    @Override
    public List<ClientParkOnRecordVo> convetParkOnVoList(List<ParkOn> parkOns) {
        return OrikaUtil.converts(parkOns, ClientParkOnRecordVo.class);
    }

    @Override
    @NeedSetFieldValue
    public AjaxResult getClientdeviceList(String clientId) {
        ParkClient parkClient = parkClientMapper.selectParkClientById(Long.valueOf(clientId));
        if (parkClient == null) {
            return null;
        }
        List<ParkDeviceNew> parkDeviceNews = parkDeviceNewMapper.getClientDeviceList(clientId);
        Map<String, Object> map = new HashMap<>(2);
        map.put("list", parkDeviceNews);
        map.put("total", parkDeviceNews.size());
        return AjaxResult.success(map);
    }

    @Override
    @NeedSetDictLabel
    public List<ClientInOutVo> convertParkInoutToVo(List<ParkInOut> parkInOuts) {
        return OrikaUtil.converts(parkInOuts, ClientInOutVo.class);
    }

    @Override
    @NeedSetDictLabel
    @NeedSetFieldValue
    public List<ParkOn> getClientParkOnList(ClientParkOnListRequest request) {
        return parkOnMapper.getClientParkOnList(request);
    }

    @Override
    public AjaxResult handOutInfo(ClientHandOutInfoRequest request) {
        request.setParkId(SecurityUtils.getParkId().toString());
        if (!StringUtils.isLegalPlate(request.getPlate())) {
            return AjaxResult.error("请输入正确的车牌");
        }

        Map<String, Object> map = new HashMap<>(16);

        // 出场数据处理
        ParkOut parkOut = parkOutService.selectParkOutById(request.getOutId());
        if (null != parkOut) {
            map.put("stopTime", parkOut.getStopTime());
            long fee = parkOut.getMayFee() - parkOut.getReduceFee() - parkOut.getActualFee();
            map.put("fee", Double.parseDouble(Long.toString(fee)) / 100);
            map.put("outTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, parkOut.getOutTime()));
            map.put("outCarPic", aliossUtil.getJzyGetObjectUrl(parkOut.getOutPic()).toString());
            String outStatusLabel = remoteSystemDictService.getDictLabel("car_pass_status", parkOut.getStatus()).getData();
            map.put("outStatusLabel", outStatusLabel);

            // 入场数据处理
            ParkIn parkIn = parkInService.selectParkInById(parkOut.getInId());
            if (parkIn != null) {
                map.put("inLaneName", parkIn.getLaneName());
                if (parkIn.getInTime() != null) {
                    map.put("inTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, parkIn.getInTime()));
                }
                map.put("inCarPlate", parkIn.getInCarPlate());
                map.put("inStatus", parkIn.getInTypeLabel());
                if (parkIn.getInPic() != null) {
                    map.put("inCarPic", aliossUtil.getJzyGetObjectUrl(parkIn.getInPic()).toString());
                }
                ParkCarMngtype parkCarMngtype = parkCarMngtypeService.selectParkCarMngtypeById(parkIn.getMngTypeId());
                if (null != parkCarMngtype) {
                    map.put("mngType", parkCarMngtype.getName());
                }

                ParkingOrder parkingOrder = new ParkingOrder();
                parkingOrder.setParkId(Long.valueOf(request.getParkId()));
                parkingOrder.setParkingSerial(parkOut.getParkingSerial());
                parkingOrder.setPlate(parkIn.getInCarPlate());
                List<ParkingOrder> parkingOrderList = parkingOrderMapper.selectParkingOrderList(parkingOrder);
                if (CollectionUtils.isEmpty(parkingOrderList)) {
                    map.put("totalFee", map.get("fee"));
                    map.put("preFee", 0);
                    map.put("coupon", 0);
                } else {
                    map.put("totalFee", Double.parseDouble(parkingOrderList.get(0).getTotalFee().toString()) / 100);
                    map.put("preFee", Double.parseDouble(parkingOrderList.get(0).getPaidFee().toString()) / 100);
                    map.put("coupon", Double.parseDouble(parkingOrderList.get(0).getCouponFee().toString()) / 100);
                }
                return AjaxResult.success(map);
            } else {
                log.warn("[PC岗亭]手动出场信息查询，根据入场ID查询入场信息为空，入场ID：{}", parkOut.getInId());
                return AjaxResult.error("入场信息不存在");
            }
        } else {
            log.warn("[PC岗亭]手动出场信息查询，根据出场ID查询出场信息为空，出场ID：{}", request.getOutId());
            return AjaxResult.error("出场信息不存在");
        }
    }

    @Override
    public AjaxResult cancelPass(ClientCancelPassRequest request) {
        ParkOut parkOut = parkOutService.selectParkOutById(request.getOutId());
        // car_pass_status  取消放行
        parkOut.setStatus("43");
        int i = parkOutMapper.updateParkOut(parkOut);
        return i > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    @Override
    public AjaxResult spaceEdit(ClientSpaceEditRequest request) {
        ParkGarage parkGarage = parkGarageService.selectParkGarageById(request.getGarageId());
        Long tempEmptySpace = parkGarage.getTempEmptySpace() + request.getTempEmptySpace();

        ParkGarage update = new ParkGarage();
        update.setId(request.getGarageId());
        update.setTempEmptySpace(tempEmptySpace);

        int count = parkGarageService.updateParkGarage(update);
        if (count <= 0) {
            return AjaxResult.error();
        }
        clientCommandService.updateSpaces(SecurityUtils.getParkId(), update.getId());
        return AjaxResult.success();
    }

    @Override
    public AjaxResult getLaneInfo(Long deviceId) {

        ParkDeviceNew deviceNew = parkDeviceNewService.selectParkDeviceNewById(deviceId);
        if (null == deviceNew) {
            return AjaxResult.error("没找到对应设备信息");
        }

        Map<String, String> map = new HashMap<>(1);
        map.put("id", "deviceId");
        ClientLaneInfoVo vo = OrikaUtil.convert(deviceNew, ClientLaneInfoVo.class, map);

        return AjaxResult.success(vo);
    }

    @Override
    @NeedSetFieldValue
    public List<ClientCashPassListVo> clientCashPassList(ClientCashPassListRequest request) {
        request.setClientId(String.valueOf(SecurityUtils.getClientId()));
        request.setParkId(String.valueOf(SecurityUtils.getParkId()));
        List<ClientCashPassListVo> cashPassList = parkingOrderMapper.selectClientCashPassList(request);
        int id = (request.getPageNum() - 1) * request.getPageSize();
        for (ClientCashPassListVo vo : cashPassList) {
            vo.setId(++id);
            vo.setOrderAmount(vo.getPayFee());
            vo.setReceivableAmounr(vo.getPayFee());
        }
        return cashPassList;
    }

    @Override
    public AjaxResult selectParkInDetail(Long inId) {
        ParkIn parkIn = parkInService.selectParkInById(inId);
        //入场记录管理类型改为文字
        if (null != parkIn.getMngTypeId()) {
            ParkCarMngtype parkCarMngType = parkCarMngtypeService.selectParkCarMngtypeById(parkIn.getMngTypeId());
            if (null != parkCarMngType) {
                parkIn.setMngType(parkCarMngType.getName());
            }
        }
        ClientParkInVo clientParkInVo = clientHomePageTransfer.parkInTransferClientParkInVo(parkIn);
        return AjaxResult.success(clientParkInVo);
    }

    @Override
    public AjaxResult selectParkOutDetail(Long outId) {
        ParkOut parkOut = parkOutService.selectParkOutById(outId);
        ParkIn parkIn = parkInService.selectParkInById(parkOut.getInId());

        ClientParkOutVo clientParkOutVo = clientHomePageTransfer.parkOutTransferClientParkOutVo(parkOut);
        if (parkIn.getInTime() != null) {
            clientParkOutVo.setInTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, parkIn.getInTime()));
        }
        clientParkOutVo.setInCarPic(aliossUtil.getJzyGetObjectUrl(parkIn.getInPic()).toString());
        clientParkOutVo.setInCarPlate(parkIn.getInCarPlate());
        clientParkOutVo.setInStatus(parkIn.getInTypeLabel());
        ParkCarMngtype parkCarMngtype = parkCarMngtypeService.selectParkCarMngtypeById(parkIn.getMngTypeId());
        if (null != parkCarMngtype) {
            clientParkOutVo.setMngType(parkCarMngtype.getName());
        }
        return AjaxResult.success(clientParkOutVo);
    }
}
